﻿using System;
using System.ComponentModel;
using System.Drawing;
using System.Linq;
using RaytracerLib.Layers;
using RaytracerLib.MathLib;
using System.Collections.Generic;
using RaytracerLib.Script;

namespace Raytracer.PropertyGridDecorators
{
    public class SolidColorLayerProperties
    {
        private SolidColorLayer m_layer;

        public SolidColorLayerProperties(SolidColorLayer a_layer)
        {
            m_layer = a_layer;
        }

        [DisplayName("System color")]
        [Category(Categories.PROPERTIES)]
        public Color SystemColor
        {
            get
            {
                return m_layer.Color.SystemColor;
            }
            set
            {
                m_layer.Color = new ColorFloat(value);
            }
        }

        [Category(Categories.PROPERTIES)]
        [TypeConverter(typeof(ColorFloatConverter))]
        public ColorFloatProperties Color
        {
            get
            {
                return new ColorFloatProperties(
                    () => m_layer.Color,
                    (c) => m_layer.Color = c);
            }
            set
            {
                m_layer.Color = value.ToColorFloat();
            }
        }
    }

    public class SolidValueLayerProperties
    {
        private SolidValueLayer m_layer;

        public SolidValueLayerProperties(SolidValueLayer a_layer)
        {
            m_layer = a_layer;
        }

        [Category(Categories.PROPERTIES)]
        [TypeConverter(typeof(DoubleConverter))]
        public double Value
        {
            get
            {
                return m_layer.Value;
            }
            set
            {
                m_layer.Value = value;
            }
        }
    }

    public class ThresholdColorOperationLayerProperties
    {
        private ThresholdColorOperationLayer m_layer;

        public ThresholdColorOperationLayerProperties(ThresholdColorOperationLayer a_layer)
        {
            m_layer = a_layer;
        }

        [DisplayName("System color")]
        [Category(Categories.PROPERTIES)]
        public Color SystemColor
        {
            get
            {
                return m_layer.Level.SystemColor;
            }
            set
            {
                m_layer.Level = new ColorFloat(value);
            }
        }

        [Category(Categories.PROPERTIES)]
        [TypeConverter(typeof(ColorFloatConverter))]
        public ColorFloatProperties Color
        {
            get
            {
                return new ColorFloatProperties(
                    () => m_layer.Level,
                    (c) => m_layer.Level = c);
            }
            set
            {
                m_layer.Level = value.ToColorFloat();
            }
        }
    }

    public class ThresholdValueOperationLayerProperties
    {
        private ThresholdValueOperationLayer m_layer;

        public ThresholdValueOperationLayerProperties(ThresholdValueOperationLayer a_layer)
        {
            m_layer = a_layer;
        }

        [Category(Categories.PROPERTIES)]
        [TypeConverter(typeof(DoubleConverter))]
        public double Value
        {
            get
            {
                return m_layer.Level;
            }
            set
            {
                m_layer.Level = value;
            }
        }
    }

    public class OffsetOperationLayerProperties
    {
        private OffsetOperationLayer m_layer;

        public OffsetOperationLayerProperties(OffsetOperationLayer a_layer)
        {
            m_layer = a_layer;
        }

        [Category(Categories.PROPERTIES)]
        [TypeConverter(typeof(Vector2Converter))]
        public Vector2Properties Offset
        {
            get
            {
                return new Vector2Properties(
                    () => m_layer.Offset,
                    (v) => m_layer.Offset = v);
            }
            set
            {
                m_layer.Offset = value.ToVector2();
            }
        }
    }

    public class ScaleOperationLayerProperties
    {
        private ScaleOperationLayer m_layer;

        public ScaleOperationLayerProperties(ScaleOperationLayer a_layer)
        {
            m_layer = a_layer;
        }

        [Category(Categories.PROPERTIES)]
        [TypeConverter(typeof(Vector2Converter))]
        public Vector2Properties Ratio
        {
            get
            {
                return new Vector2Properties(
                    () => m_layer.Ratio,
                    (v) => m_layer.Ratio = v);
            }
            set
            {
                m_layer.Ratio = value.ToVector2();
            }
        }
    }

    public class TransformOperationLayerProperties
    {
        private TransformOperationLayer m_layer;

        public TransformOperationLayerProperties(TransformOperationLayer a_layer)
        {
            m_layer = a_layer;
        }

        [Category(Categories.PROPERTIES)]
        [TypeConverter(typeof(Matrix3Converter))]
        public Matrix3Properties Transform
        {
            get
            {
                return new Matrix3Properties(
                    () => m_layer.Transform,
                    (v) => m_layer.Transform = v);
            }
            set
            {
                m_layer.Transform = value.ToMatrix3();
            }
        }
    }

    public class ProceduralLayerProperties
    {
        ProceduralLayer m_layer;

        public ProceduralLayerProperties(ProceduralLayer a_layer)
        {
            m_layer = a_layer;
        }

        [Category(Categories.PROPERTIES)]
        [TypeConverter(typeof(MultilineStringConverter))]
        public string[] Script
        {
            get
            {
                return m_layer.Script.Replace(
                    System.Environment.NewLine, "\n").Split(new[] { '\n' }).ToArray();
            }
            set
            {
                m_layer.Script = String.Join(System.Environment.NewLine, value);
            }
        }

        [Category(Categories.PROPERTIES)]
        public string[] ScriptPreview
        {
            get
            {
                return m_layer.Script.Replace(
                    System.Environment.NewLine, "\n").Split(new[] { '\n' }).ToArray();
            }
        }
    }
}